import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Arrays;
import java.time.LocalDate;

public class Main {
    private static List<Task> tasks = new ArrayList<>();
    private static List<Task> completedTasks = new ArrayList<>();
    private static List<User> users;
    private static Scanner scanner = new Scanner(System.in);
    private static User currentUser;

    public static void main(String[] args) {
        // 初始化数据库
        DatabaseManager.initDatabase();
        // 加载所有用
        users = DatabaseManager.loadUsers();

        // 创建提醒线程
        Thread reminderThread = new Thread(() -> {
            while (true) {
                if (currentUser != null) {
                    checkReminders();
                }
                try {
                    Thread.sleep(60000);
                } catch (InterruptedException e) {
                    break;
                }
            }
        });
        reminderThread.setDaemon(true);
        reminderThread.start();

        while (true) {
            showLoginPage();
        }
    }

    private static void showLoginPage() {
        System.out.println("#######################");
        System.out.println("欢迎进入待办管理系统");
        System.out.println("1. 登陆");
        System.out.println("2. 注册");
        System.out.println("3. 退出系统");
        System.out.println("#######################");

        String choice = scanner.nextLine();
        if (choice.equals("1")) {
            login();
        } else if (choice.equals("2")) {
            register();
        } else if (choice.equals("3")) {
            System.out.println("感谢使用，再见！");
            System.exit(0);
        } else {
            System.out.println("无效选项，请重新选择。");
        }
    }

    private static void login() {
        while (true) {
            String username = getNonEmptyInput("请输入邮箱: ");
            String password = getNonEmptyInput("请输入密码: ");

            for (User user : users) {
                if (user.getUsername().equals(username) && user.getPassword().equals(password)) {
                    currentUser = user;
                    tasks = DatabaseManager.loadTasks(currentUser.getUserId());
                    completedTasks = DatabaseManager.loadCompletedTasks(currentUser.getUserId());
                    showHomePage();
                    return;
                }
            }
            System.out.println("邮箱或密码错误！");
            if (getValidYesNo("是否重新输入？(y/n)").equalsIgnoreCase("n")) {
                return;
            }
        }
    }

    private static void register() {
        System.out.print("请输入邮箱: ");
        String email = scanner.nextLine();

        // 验证邮箱格式
        if (!EmailSender.isValidEmail(email)) {
            System.out.println("邮箱格式不正确，请重新输入。");
            return;
        }

        // 检查邮箱是否已存在
        for (User user : users) {
            if (user.getUsername().equals(email)) {
                System.out.println("该邮箱已注册，请直接登录。");
                return;
            }
        }

        // 发送验证码
        System.out.println("正在发送验证码到您的邮箱...");
        String verificationCode = EmailSender.sendVerificationCode(email);

        // 等待用户输入验证码
        System.out.print("请输入收到的验证码: ");
        String inputCode = scanner.nextLine();

        // 验证验证码
        if (!EmailSender.verifyCode(email, inputCode)) {
            System.out.println("验证码错误或已过期，注册失败。");
            return;
        }

        System.out.print("请输入密码: ");
        String password = scanner.nextLine();

        // 创建新用户并保存到数据库
        User newUser = new User(email, password);
        DatabaseManager.saveUser(newUser);
        users = DatabaseManager.loadUsers(); // 重新加载用户列表
        System.out.println("注册成功，请返回登录界面登录");
    }

    private static void showHomePage() {
        while (true) {
            // 每次显示主页面时检查提醒
            checkReminders();

            System.out.println("#######################");
            System.out.println("欢迎来到待办管理系统");
            System.out.println("1. 创建待办");
            System.out.println("2. 管理待办");
            System.out.println("3. 退出登陆");
            System.out.println("#######################");

            String choice = scanner.nextLine();
            if (choice.equals("1")) {
                createTodo();
            } else if (choice.equals("2")) {
                showManageTodoPage();
            } else if (choice.equals("3")) {
                System.out.println("退出成功！");
                break;
            } else {
                System.out.println("无效选项请重新选择。");
            }
        }
    }

    private static void createTodo() {
        // 获取任务标题
        String title = getNonEmptyInput("请输入任务标题: ");

        // 获取任务描述
        String description = getNonEmptyInput("请输入任务描述: ");

        // 设置优先级
        System.out.println("请设置优先级");
        System.out.println("1. 高优先级");
        System.out.println("2. 中优先级");
        System.out.println("3. 低优先级");
        String priority = getPriorityFromChoice(getValidInput("请选择优先级: ",
                new String[]{"1", "2", "3"}));

        Task task = new Task(currentUser.getUserId(), title, description, priority);

        // 添加标签
        if (getValidYesNo("是否添加标签？(y/n)").equalsIgnoreCase("y")) {
            while (true) {
                System.out.println("请输入标签（多个标签用逗号分隔）：");
                String tagsInput = scanner.nextLine().trim();
                if (!tagsInput.isEmpty()) {
                    String[] tags = tagsInput.split(",");
                    task.getTags().addAll(Arrays.asList(tags));
                    break;
                }
                System.out.println("标签不能为空，请重新输入:");
            }
        }

        // 设置截止日期
        if (getValidYesNo("是否设置截止日期？(y/n)").equalsIgnoreCase("y")) {
            LocalDateTime dueDate = null;
            while (dueDate == null) {
                dueDate = inputDateTime("请输入截止日期：");
                if (dueDate == null) {
                    if (getValidYesNo("是否重新输入截止日期？(y/n)").equalsIgnoreCase("n")) {
                        break;
                    }
                }
            }

            if (dueDate != null) {
                task.setDueDate(dueDate);

                // 询问是否需要提醒
                if (getValidYesNo("是否在截止时间前15分钟提醒？(y/n)").equalsIgnoreCase("y")) {
                    task.setReminderTime(dueDate.minusMinutes(15));
                    System.out.println("提醒设置成功！");
                }
            }
        }

        // 保存到数据库
        DatabaseManager.saveTask(task);
        tasks.add(task);
        System.out.println("创建成功!");

        // 询问是否继续创建
        if (getValidYesNo("是否继续创建待办？(y/n)").equalsIgnoreCase("y")) {
            createTodo();  // 递归调用创建新的待办
        }
    }

    private static void showManageTodoPage() {
        while (true) {
            if (tasks.isEmpty()) {
                System.out.println("#######################");
                System.out.println("没有待办事项可管理。");
                System.out.println("1. 查询已完成的待办事项");
                System.out.println("2. 返回主页面");
                System.out.println("#######################");

                String choice = scanner.nextLine();
                if (choice.equals("1")) {
                    showCompletedTodos();
                } else if (choice.equals("2")) {
                    return;
                } else {
                    System.out.println("无效选项，请重新选择。");
                }
            } else {
                // 显示所有待办事项
                System.out.println("#######################");
                System.out.println("待办事项列表:");
                for (int i = 0; i < tasks.size(); i++) {
                    System.out.println((i + 1) + ". " + tasks.get(i));
                }
                System.out.println("-----------------------");
                System.out.println("请选择操作：");
                System.out.println("输入待办编号进行管理");
                System.out.println("输入 'v' 查看已完成的待办");
                System.out.println("输入 'f' 筛选待办");
                System.out.println("输入 'q' 返回主页面");
                System.out.println("#######################");

                String input = scanner.nextLine();

                if (input.equalsIgnoreCase("q")) {
                    return;
                } else if (input.equalsIgnoreCase("v")) {
                    showCompletedTodos();
                    continue;
                } else if (input.equalsIgnoreCase("f")) {
                    showFilterOptions();
                    continue;
                }

                // 尝试解析待办编号
                try {
                    int index = Integer.parseInt(input) - 1;
                    if (index >= 0 && index < tasks.size()) {
                        showTaskManageOptions(index);
                    } else {
                        System.out.println("无效的待办编号！");
                    }
                } catch (NumberFormatException e) {
                    System.out.println("无效的输入！");
                }
            }
        }
    }

    private static void showTaskManageOptions(int taskIndex) {
        Task task = tasks.get(taskIndex);
        while (true) {
            System.out.println("#######################");
            System.out.println("当前待办：" + task.getTitle());
            System.out.println("1. 完成待办");
            System.out.println("2. 删除待办");
            System.out.println("3. 设置提醒");
            System.out.println("4. 更改优先级");
            System.out.println("5. 更新任务信息");
            System.out.println("6. 返回待办列表");
            System.out.println("#######################");

            String choice = scanner.nextLine();
            switch (choice) {
                case "1":
                    completeTodo(taskIndex);
                    return; // 完成后返回上级菜单
                case "2":
                    deleteTodo(taskIndex);
                    return; // 删除后返回上级菜单
                case "3":
                    setReminder(taskIndex);
                    break;
                case "4":
                    changePriority(taskIndex);
                    break;
                case "5":
                    updateTask(taskIndex);
                    break;
                case "6":
                    return;
                default:
                    System.out.println("无效选项，请重新选择。");
            }
        }
    }

    private static void completeTodo(int index) {
        Task task = tasks.get(index);
        task.setStatus(true);
        DatabaseManager.updateTask(task);
        tasks.remove(index);
        completedTasks.add(task);
        System.out.println("任务已完成！");
    }

    private static void deleteTodo(int index) {
        Task task = tasks.get(index);
        DatabaseManager.deleteTask(task.getTaskId());
        tasks.remove(index);
        System.out.println("任务已删除！");
    }

    private static void setReminder(int index) {
        Task task = tasks.get(index);
        if (task.getDueDate() != null) {
            System.out.println("是否在截止时间前15分钟提醒？(y/n)");
            if (scanner.nextLine().equalsIgnoreCase("y")) {
                task.setReminderTime(task.getDueDate().minusMinutes(15));
                DatabaseManager.updateTask(task);
                System.out.println("提醒设置成功！");
                System.out.println("截止时间: " +
                        task.getDueDate().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm")));
                System.out.println("提醒时间: " +
                        task.getReminderTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm")));
            } else {
                task.setReminderTime(null);
                DatabaseManager.updateTask(task);
                System.out.println("已取消提醒设置。");
            }
        } else {
            System.out.println("该任务没有设置截止时间，无法设置提醒。");
        }
        System.out.println("按任意键继续...");
        scanner.nextLine();
    }

    private static void changePriority(int taskIndex) {
        Task task = tasks.get(taskIndex);
        System.out.println("请设置优先级");
        System.out.println("1. 高优先级");
        System.out.println("2. 中优先级");
        System.out.println("3. 低优先级");
        System.out.println("4. 返回上级菜单");

        String priorityChoice = scanner.nextLine();
        if (priorityChoice.equals("4")) {
            return;
        }

        String priority = getPriorityFromChoice(priorityChoice);
        if (priority.isEmpty()) {
            System.out.println("无效的优先级选项。");
            return;
        }

        task.setPriority(priority);
        DatabaseManager.updateTask(task);
        System.out.println("优先级已更改！");
    }

    private static void showCompletedTodos() {
        if (completedTasks.isEmpty()) {
            System.out.println("#######################");
            System.out.println("没有已完成的待办事项。");
        } else {
            System.out.println("#######################");
            System.out.println("已完成的待办事项:");
            for (Task task : completedTasks) {
                System.out.println("- " + task.toString());
            }
        }
        System.out.println("按任意键返回。");
        scanner.nextLine();
    }

    private static void checkReminders() {
        for (Task task : tasks) {
            if (task.needsReminder()) {
                String subject = "待办事项截止提醒";
                String content = task.getReminderMessage();
                EmailSender.sendEmail(currentUser.getUsername(), subject, content);

                // 置提醒时间为当前时间，表示已经发送过提醒
                task.setReminderTime(LocalDateTime.now());
                DatabaseManager.updateTask(task);
            }
        }
    }

    private static String getPriorityFromChoice(String choice) {
        switch (choice) {
            case "1":
                return "高优先级";
            case "2":
                return "中优先级";
            case "3":
                return "低优先级";
            default:
                return "";
        }
    }

    private static void showFilterOptions() {
        while (true) {
            System.out.println("#######################");
            System.out.println("筛选选项:");
            System.out.println("1. 按标签筛选");
            System.out.println("2. 按优先级筛选");
            System.out.println("3. 返回上级菜单");
            System.out.println("#######################");

            String choice = scanner.nextLine();
            switch (choice) {
                case "1":
                    filterByTags();
                    break;
                case "2":
                    filterByPriority();
                    break;
                case "3":
                    return;
                default:
                    System.out.println("无效选项，请重新选择。");
            }
        }
    }

    private static void filterByTags() {
        while (true) {
            String tag = getNonEmptyInput("请输入要筛选的标签: ");

            System.out.println("符合条件的任务:");
            boolean found = false;
            for (Task task : tasks) {
                if (task.getTags().contains(tag)) {
                    System.out.println("- " + task.toString());
                    found = true;
                }
            }

            if (!found) {
                System.out.println("没有找到包含该标签的任务。");
                if (getValidYesNo("是否尝试其他标签？(y/n)").equalsIgnoreCase("n")) {
                    break;
                }
            } else {
                break;
            }
        }
        System.out.println("按任意键返回。");
        scanner.nextLine();
    }

    private static void filterByPriority() {
        while (true) {
            System.out.println("选择优先级:");
            System.out.println("1. 高优先级");
            System.out.println("2. 中优先级");
            System.out.println("3. 低优先级");
            System.out.println("4. 返回上级菜单");

            String choice = getValidInput("请选择: ", new String[]{"1", "2", "3", "4"});
            if (choice.equals("4")) {
                return;
            }

            String priority = getPriorityFromChoice(choice);
            System.out.println("符合条件的任务:");
            boolean found = false;
            for (Task task : tasks) {
                if (task.getPriority().equals(priority)) {
                    System.out.println("- " + task.toString());
                    found = true;
                }
            }

            if (!found) {
                System.out.println("没有找到该优先级的任务。");
                if (getValidYesNo("是否选择其他优先级？(y/n)").equalsIgnoreCase("n")) {
                    break;
                }
            } else {
                break;
            }
        }
        System.out.println("按任意键返回。");
        scanner.nextLine();
    }

    private static void updateTask(int taskIndex) {
        Task task = tasks.get(taskIndex);
        while (true) {
            System.out.println("#######################");
            System.out.println("当前任务：" + task.getTitle());
            System.out.println("1. 更新标题");
            System.out.println("2. 更新描述");
            System.out.println("3. 更新截止日期");
            System.out.println("4. 更新标签");
            System.out.println("5. 返回上级菜单");
            System.out.println("#######################");

            String choice = getValidInput("请选择操作: ", new String[]{"1", "2", "3", "4", "5"});
            if (choice.equals("5")) {
                return;
            }

            switch (choice) {
                case "1":
                    task.setTitle(getNonEmptyInput("请输入新标题: "));
                    break;
                case "2":
                    task.setDescription(getNonEmptyInput("请输入新描述: "));
                    break;
                case "3":
                    LocalDateTime dueDate = inputDateTime("请输入新截止日期：");
                    if (dueDate != null) {
                        task.setDueDate(dueDate);
                        if (getValidYesNo("是否需要设置提醒？(y/n)").equalsIgnoreCase("y")) {
                            task.setReminderTime(dueDate.minusMinutes(15));
                            System.out.println("提醒设置成功！");
                        }
                    }
                    break;
                case "4":
                    while (true) {
                        System.out.println("请输入新标签（多个标签用逗号分隔）：");
                        String tagsInput = scanner.nextLine().trim();
                        if (!tagsInput.isEmpty()) {
                            String[] tags = tagsInput.split(",");
                            task.getTags().clear();
                            task.getTags().addAll(Arrays.asList(tags));
                            break;
                        }
                        System.out.println("标签不能为空！");
                        if (getValidYesNo("是否重新输入？(y/n)").equalsIgnoreCase("n")) {
                            return;
                        }
                    }
                    break;
            }

            DatabaseManager.updateTask(task);
            System.out.println("更新成功！");

            if (getValidYesNo("是否继续更新该任务？(y/n)").equalsIgnoreCase("n")) {
                break;
            }
        }
    }

    private static LocalDateTime inputDateTime(String prompt) {
        while (true) {
            try {
                System.out.println(prompt);
                int year = getValidInput("年份 (2024-2100): ", 2024, 2100);
                int month = getValidInput("月份 (1-12): ", 1, 12);
                int maxDay = getMaxDaysInMonth(year, month);
                int day = getValidInput("日期 (1-" + maxDay + "): ", 1, maxDay);
                int hour = getValidInput("小时 (0-23): ", 0, 23);
                int minute = getValidInput("分钟 (0-59): ", 0, 59);

                LocalDateTime dateTime = LocalDateTime.of(year, month, day, hour, minute);
                if (dateTime.isBefore(LocalDateTime.now())) {
                    System.out.println("错误：不能设置过去的时间！");
                    if (getValidYesNo("是否重新输入？(y/n)").equalsIgnoreCase("n")) {
                        return null;
                    }
                    continue;
                }
                return dateTime;
            } catch (Exception e) {
                System.out.println("日期时间输入错误！");
                if (getValidYesNo("是否重新输入？(y/n)").equalsIgnoreCase("n")) {
                    return null;
                }
            }
        }
    }

    private static int getValidInput(String prompt, int min, int max) {
        while (true) {
            System.out.print(prompt);
            String input = scanner.nextLine();
            if (isValidInput(input, min, max)) {
                return Integer.parseInt(input);
            }
            System.out.println("请输入" + min + "-" + max + "之间的数字！");
        }
    }

    private static int getMaxDaysInMonth(int year, int month) {
        return LocalDate.of(year, month, 1)
                .lengthOfMonth();
    }

    private static boolean isValidInput(String input, int min, int max) {
        try {
            int value = Integer.parseInt(input);
            return value >= min && value <= max;
        } catch (NumberFormatException e) {
            return false;
        }
    }

    private static String getValidInput(String prompt, String[] validOptions) {
        while (true) {
            System.out.println(prompt);
            String input = scanner.nextLine().trim();

            for (String option : validOptions) {
                if (input.equalsIgnoreCase(option)) {
                    return input;
                }
            }

            System.out.println("无效输入！有效选项: " + String.join(", ", validOptions));
            System.out.println("请重新输入:");
        }
    }

    private static String getValidYesNo(String prompt) {
        return getValidInput(prompt, new String[]{"y", "n"});
    }

    private static String getNonEmptyInput(String prompt) {
        while (true) {
            System.out.print(prompt);
            String input = scanner.nextLine().trim();
            if (!input.isEmpty()) {
                return input;
            }
            System.out.println("输入不能为空，请重新输入:");
        }
    }
}